<?php

class Public_CommentsModel extends BlogPublicBaseModel
{
    /**
     * Get comment object.
     *
     * @param integer $comment_id
     * @return Comment|bool
     */
    public function getComment($comment_id)
    {
        return Doctrine::getTable('Comment')->find($comment_id);
    }
    
	/**
	 * Find comments for given post.
	 *
	 * @param Post $post
	 * @return Doctrine_Collection
	 */
	public function findBlogPostComments(Post $post)
	{
        $query = Doctrine_Query::create()
            ->from('Comment c')
            ->where('c.parent_id IS NULL and c.post_id = ?', $post->id)
            ;
        $result = $query->execute();
        return $result;
	}
	
	/**
	 * Count comments number for given post.
	 *
	 * @param Post $post
	 * @param boolean $include_not_approved
	 */
	public function getBlogPostCommentsCount(Post $post, $include_not_approved=FALSE)
	{
        $query = Doctrine_Query::create()
            ->from('Comment c')
            ->where('c.post_id = ?', $post->id);
        if (!$include_not_approved) {
            $query->andWhere('c.is_approved = ?', true);
        }
        $res = $query->execute();
        $cnt = $res->count();
        $res->free();

	    return $cnt;
	}
	
	
	/**
	 * Retrieve Comment instance
	 *
	 * @param Post $post
	 * @param int $comment_id
	 * @param Comment instance of Comment type or FALSE if there are no such comment for given post
	 */
	public function getBlogPostComment(Post $post, $comment_id)
	{
        $c = $this->getComment($comment_id);
        if ($c->post_id != $post->id) {
            return FALSE;
        }
	    
	    return $c;
	}
	
	/**
	 * Retrieve list of not yet approved comments.
	 * 
	 * @return DoctrineCollection
	 */
	public function findNotApprovedComments()
	{
        $query = Doctrine_Query::create()
            ->from('Comment c')
            ->where('c.is_approved = ?', false);
	    
	    return $query->execute();
	}
	
	/**
	 * Update comment.
	 *
	 * @param integer $comment_id
	 * @param boolean $approved TRUE, FALSE or null
	 * @throws CommentNotFoundException,Doctrine_Exception
	 */
	public function updateComment($comment_id, $approved)
	{
	    $comment = $this->getComment($comment_id);
	    if (!$comment instanceof Comment) {
	        throw new CommentNotFoundException();
	    }
	    
        $con = $this->getPdo();
        $con->beginTransaction();
	    
        try {
            $modified = FALSE;
            
            if (!is_null($approved)) {
                $modified = TRUE;
                $comment->is_approved = $approved;
            }
            
            if ($modified) {
                $comment->save($con);
                $con->commit();
            } else {
                $con->rollBack();
            }
        } catch (Doctrine_Exception $e) {
            $con->rollBack();
            throw $e;
        }
	}
	
	/**
	 * Add new comment
	 *
	 * @param Post $post
	 * @param mixed $user null or User object
	 * @param boolean $is_owner
	 * @param mixed $parent null or Comment instance
	 * @param string $name
	 * @param string $email
	 * @param string $body
	 * @param boolean $approved
	 * @return Comment
	 */
	public function addComment(Post $post, $user, $is_owner, $parent, $display_name, $email, $website, $body, $approved)
	{
	    $con = $this->getPdo();
	    $con->beginTransaction();
	    $comment = null;
	    try {
	        /* @var $comment Comment */
	        $comment = new Comment();
	        $comment->comment_time = date_create()->format('Y-m-d H:i:s');
	        if ($parent instanceof Comment) {
	            $comment->parent_id = $parent->id;
	        }
            $comment->is_owner_comment = $is_owner === TRUE;

	        $comment->comment_text = $body;

	        if (!is_null($website) && $website !== '') {
	            $comment->website = $website;
	        }
	        if ($user instanceof User) {
	            $comment->User = $user;
	        } else {
	            $comment->display_name = $display_name;
	            $comment->email = $email;
	        }
            $comment->is_approved = $approved === TRUE;
	        $comment->save($con);
	        $post->Comments->add($comment);
	        $post->save($con);
	        $con->commit();
	    } catch (Doctrine_Exception $e) {
            $con->rollBack();
            throw $e;
	    }
	    
	    return $comment;
	}
	
	/**
	 * Delete comment (and all subcomments).
	 *
	 * @param integer $comment_id
	 * @throws Doctrine_Exception
	 */
    public function deleteComment($comment_id)
    {
        $comment = $this->getComment($comment_id);
        $con = $this->getPDO();
        
        $con->beginTransaction();
        try {
            $comment->delete($con);
            $con->commit();
        } catch (Doctrine_Exception  $e) {
            $con->rollback();
            throw $e;
        }
    }
    
    /**
     * Delete comments and subcomments too.
     *
     * @param array $comments list of comments id to delete
     */
    public function deleteComments($comments)
    {
        $con = $this->getPDO();
        $con->beginTransaction();
        
        if (!$comments) {
            return;
        }

        foreach ($comments as $comment_id) {
            $comment = $this->getComment($comment_id);
            if (is_null($comment)) {
                continue;
            }
            
            try {
                $comment->delete($con);
            } catch (Doctrine_Exception  $e) {
                // do nothing
            }
        }
        $con->commit();
    }
}
